﻿using Aop.Api;
using Aop.Api.Domain;
using Aop.Api.Request;
using Aop.Api.Response;
using Flurl.Http;
using Pay.Core;
using Pay.Core.AliPay;
using Pay.DTO;
using Pay.IService;
using Pay.TO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Pay.Service.Pay
{
    public class AliPayService : ServiceBase2, IPayService, IDisposable
    {
        private ISettingService _iSettingService;
        private IMerchantService _iMerchantService;
        private IChargeService _iChargeService;
        private IPayHtmlService _iPayHtmlService;
        private IOrderService _iOrderService;
        private IPayNotifyService _iPayNotifyService;
        private static readonly object _onlyRedDrillPayLock = new object();
        public AliPayService(IUnitOfWork iUnitOfWork, ISettingService iSettingService,
                            IMerchantService iMerchantService, IChargeService iChargeService,
                            IPayHtmlService iPayHtmlService, IOrderService iOrderService,
                            IPayNotifyService iPayNotifyService) : base(iUnitOfWork)
        {
            _iSettingService = iSettingService;
            _iMerchantService = iMerchantService;
            _iChargeService = iChargeService;
            _iPayHtmlService = iPayHtmlService;
            _iOrderService = iOrderService;
            _iPayNotifyService = iPayNotifyService;
        }

        public Task<transfer_result> AgencyFund(apply_receive model)
        {
            throw new NotImplementedException();
        }

        public Task<certify_verify_result> CertifyVerify(certify_verify model)
        {
            throw new NotImplementedException();
        }

        public int DealItp(long id)
        {
            throw new NotImplementedException();
        }

        public Task<gateway_pay_result> GatewayPay(gateway_pay_model model)
        {
            throw new NotImplementedException();
        }

        public List<type_setting> GatewayPayBank()
        {
            throw new NotImplementedException();
        }

        public Task<pay_notity> GatewayPayQuery(refund_model_query model)
        {
            throw new NotImplementedException();
        }

        public Task<refund_result> GatewayPayRefund(refund_model model)
        {
            throw new NotImplementedException();
        }

        public Task<refund_result> GatewayRefundQuery(refund_model_query model)
        {
            throw new NotImplementedException();
        }

        public Task<ApiResultMessage> InsteadReceive(verify_model_sms model)
        {
            throw new NotImplementedException();
        }

        public Task<ApiResultMessage> InsteadReceive(verify_model model)
        {
            throw new NotImplementedException();
        }

        public Task<int> ItpToFile(DateTime create_date)
        {
            throw new NotImplementedException();
        }

        public Task<native_result> NativePay(native_model obj)
        {
            throw new NotImplementedException();
        }

        public async Task<mall_result> MallPay(mall_model model)
        {
            var log = IocHelper.Get<ILogHelper>("info");
            var id = Guid.NewGuid().ToString("N");
            var notifyUrl = string.Format("{0}/pay/alipay_notify/{1}", _iSettingService.Get().site.api_url, id);
            var shipping = new shipping_dto();
            if (model.shipping != null)
            {
                shipping.ship_to = model.shipping.ship_to;
                shipping.region_id = model.shipping.area_id.HasValue ? model.shipping.area_id.Value : model.shipping.city_id;
                shipping.phone = model.shipping.phone; shipping.address = model.shipping.address;
                shipping.region_name = model.shipping.region_name;
            }
            model.orders.ForEach(c => { c.shipping_type = model.shipping_type; c.shipping = shipping; });
            var charge = _iChargeService.AddByMallPay(model);
            var pay_html = new pay_html_dto
            {
                id = id,
                html = model.orders.ToJson(),
                merchant_no = model.merchant_no,
                order_no = model.order_no,
                charge = charge.ToJson()
            };
            var ok = _iPayHtmlService.Save(pay_html);
            if (ok)
            {
                //订单为全额积分抵扣不需要调起第三方微信支付
                if (charge.pay_amount == 0)
                {
                    _iOrderService.PaySuceess(pay_html, "", DateTime.Now);
                    var notifyResult = await Notify(charge.merchant_no, charge.order_no);
                    if (notifyResult != "OK")
                    {
                        //创建通知消息对象
                        _iPayNotifyService.Save(new pay_notify_dto
                        {
                            merchant_no = charge.merchant_no,
                            order_no = charge.order_no,
                            pay_channel = charge.pay_info.pay_channel,
                            type = 1,
                            status = 2,
                            create_time = DateTime.Now
                        });
                        return ApiResultToJson.Json(new mall_result { order_no = model.order_no, transaction_no = model.transaction_no, is_open = false });
                    }
                    return ApiResultToJson.Json<mall_result>("订单异步通知异常");
                }
                else
                {
                    try
                    {
                        IAopClient client = new DefaultAopClient("https://openapi.alipay.com/gateway.do", AliPayV3Info.AppId, AliPayV3Info.PrivateKey, "json", "1.0", "RSA2", AliPayV3Info.PublicKey, "UTF-8", false);
                        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
                        AlipayTradeAppPayModel payModel = new AlipayTradeAppPayModel();
                        payModel.Body = model.body;
                        payModel.Subject = model.subject;
                        int.TryParse(model.tran_amount, out var amount);
                        var tran_amount = Math.Round((double)(amount / 100), 2);
                        payModel.TotalAmount = tran_amount.ToString();
                        payModel.ProductCode = "QUICK_MSECURITY_PAY";
                        payModel.OutTradeNo = model.order_no;
                        payModel.TimeoutExpress = "30m";
                        request.SetBizModel(payModel);
                        request.SetNotifyUrl(notifyUrl);
                        AlipayTradeAppPayResponse response = client.SdkExecute(request);
                        //string result = HttpUtility.HtmlEncode(response.Body);
                        var data = new mall_result { order_no = model.order_no, code_url = response.Body, is_open = true };
                        return ApiResultToJson.Json(data);
                    }
                    catch (Exception ex)
                    {
                        log.Info(ex.Message);
                    }
                }
            }

            return await ApiResultToJson.JsonAsync<mall_result>("h5支付失败");
        }

        public Task<merchant_register_result> MerchantRegister(merchant_register_model dto, string opt)
        {
            throw new NotImplementedException();
        }

        public Task<merchant_register_result> MerchantRegister(long bind_id, string settle_type, PayChannel channel = PayChannel.None)
        {
            throw new NotImplementedException();
        }

        public Task<merchant_register_result> MerchantModify(long bind_id, string settle_type, PayChannel channel = PayChannel.None)
        {
            throw new NotImplementedException();
        }

        public async Task<string> Notify(string merchant_no, string order_no)
        {
            string result = string.Empty;
            charge_dto order = _iChargeService.Get(merchant_no, order_no);
            try
            {
                var data = new pay_notity
                {
                    tran_amount = ((int)(order.order_amount * 100)).ToString(),
                    order_no = order.order_no,
                    transaction_no = order.pay_info.transaction_no,
                    pay_time = order.pay_info.pay_time.HasValue ? order.pay_info.pay_time.Value : order.order_time,
                    status = (order.status == ChargeStatus.Finish ? 1 : 2)
                };
                data.result_msg = (data.status == 1 ? "支付成功" : order.fail);
                if (string.IsNullOrEmpty(order.notify)) return "OK";
                var notify_result = await order.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveJson<ResultMessage<string>>();
                result = notify_result.data;
                var log = IocHelper.Get<ILogHelper>("info");
                log.Info(order.order_no + ":" + notify_result.ToJson());
            }
            catch (Exception ex)
            {
                var log = IocHelper.Get<ILogHelper>("info");
                log.Error("订单通道查询异常:" + order.order_no);
                string message = string.Format("消息类型：{0}\r\n消息内容：{1}\r\n引发异常的方法：{2}\r\n引发异常源：{3}"
                                , ex.GetType().Name, ex.Message, ex.TargetSite, ex.Source + ex.StackTrace);
                log.Error(message);
            }
            return result;
        }

        public Task<string> NotifyTransfer(string merchant_no, string order_no)
        {
            throw new NotImplementedException();
        }

        public Task<quota_result> Quota(string merchant_no, string busiType)
        {
            throw new NotImplementedException();
        }

        public Task<quick_pay_result> QuickPay(quick_pay_model model)
        {
            throw new NotImplementedException();
        }

        public Task<ApiResultMessage> QuickPaySendsms(quick_sendsms_model model)
        {
            throw new NotImplementedException();
        }

        public Task<quick_pay_result> QuickPay(quick_sms_model model)
        {
            throw new NotImplementedException();
        }

        public Task<pay_notity> QuickPayQuery(refund_model_query model)
        {
            throw new NotImplementedException();
        }

        public Task<refund_result> QuickPayRefund(refund_model model)
        {
            throw new NotImplementedException();
        }

        public Task<refund_result> QuickPayRefundQuery(refund_model_query model)
        {
            throw new NotImplementedException();
        }

        public Task<transfer_result> Transfer(apply_transfer model)
        {
            throw new NotImplementedException();
        }

        public Task<transfer_result> ReTransfer(long id)
        {
            throw new NotImplementedException();
        }

        public Task<batch_transfer_result> Transfer(batch_transfer model)
        {
            throw new NotImplementedException();
        }

        public Task<int> TransferNotify(long batchId, string batchFileName, long merchant_id)
        {
            throw new NotImplementedException();
        }

        public Task<int> TransferBack(long batchId, string noticeTranId, long merchant_id)
        {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TransferQuery(transfer_query model)
        {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TokenTransfer(long id)
        {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TokenTransferQuery(transfer_query model)
        {
            throw new NotImplementedException();
        }
    }
}
